package org.chaiyi.template.app.demo;

import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.chaiyi.template.contract.demo.Demo;
import org.chaiyi.template.contract.demo.IDemoService;
import org.chaiyi.template.contract.supporter.CounterSetting;
import org.chaiyi.template.core.framework.mongo.Repository;
import org.chaiyi.template.core.framework.redis.RedisUtils;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.time.temporal.ChronoUnit;

import static org.chaiyi.template.contract.demo.IDemoService.Caches.FIND_BY_ID;
import static org.chaiyi.template.contract.demo.IDemoService.Error.*;


@Slf4j
@Service
@RequiredArgsConstructor
public class DemoService implements IDemoService {

    private final RedisUtils redisUtils;
    private final Repository<CounterSetting, Demo> demoRepository;

    /**
     * 演示产生业务异常
     */
    public Mono<Demo> businessError() {
        ERROR_DEMO.trigger();
        return null;
    }

    /**
     * 演示系统异常
     */
    public Mono<Demo> systemError() {
        throw new NullPointerException("must not null !");
    }

    /**
     * 演示创建前处理
     */
    @Override
    public Demo createBefore(String tenantId, String buCode, Demo entity) {
        entity.setName(entity.getName() + "-before");
        log.info("【createBefore】tenantId->{},buCode->{},entity->{}", tenantId, buCode, JSONUtil.toJsonStr(entity));
        return entity;
    }

    /**
     * 演示创建后处理
     */
    @Override
    public void createAfter(String tenantId, String buCode, Demo entity) {
        log.info("【createAfter】异步处理~");
    }

    @Override
    public void deleteBefore(String tenantId, String buCode, String id) {
        log.info("【删除前校验】tenantId->{},buCode->{},id->{}", tenantId, buCode, id);
    }

    @Override
    public void deleteAfter(String tenantId, String buCode, Demo entity) {
        log.info("【删除后异步操作】tenantId->{},buCode->{},entity->{}", tenantId, buCode, entity);
    }

    public Mono<Boolean> setString(String tenantId, String buCode, String value) {
        return redisUtils.set("testKey", value);
    }

    public Mono<String> getString(String tenantId, String buCode) {
        return redisUtils.get("testKey", String.class);
    }
    public Mono<Demo> findByRedis(String tenantId, String buCode, String id) {
        return redisUtils.get(FIND_BY_ID + id, Demo.class)
                .switchIfEmpty(demoRepository.findItem(tenantId, buCode, id))
                .publishOn(Schedulers.boundedElastic())
                .doOnSuccess(x -> redisUtils.set(FIND_BY_ID + id, x, 1, ChronoUnit.MINUTES).subscribe());
    }

}
